package com.test.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.MissingResourceException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Date Utility Class This is used to convert Strings to Dates and Timestamps
 * <p>
 * <a href="DateUtil.java.html"><i>View Source</i></a>
 * </p>
 * 
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a> Modified by
 *         <a href="mailto:dan@getrolling.com">Dan Kibler </a> to correct time
 *         pattern. Minutes should be mm not MM (MM is month).
 * @version $Revision: 1.1 $ $Date: 2009/07/17 03:29:17 $
 */
public class DateUtils {

	// ~ Static fields/initializers
	// =============================================

	private static String defaultDatePattern = null;

	private static final int HOUR = 24;

	private static Log log = LogFactory.getLog(DateUtils.class);

	private static final int MILLSECOND = 1000;

	private static final int MINITE = 60;

	private static final int SECOND = 60;

	private static String timePattern = "HH:mm:ss";

	// ~ Methods
	// ================================================================

	/**
	 * 比较两个时间相差的天数
	 * 
	 * @param date指定时间
	 *            ("yyyy-mm-dd" 形式)
	 */
	public static int compareTime(long start, long end) {
		int i = 0;
		try {
			i = (int) ((end - start) / 24 / 3600 / 1000);
		}
		catch (Exception e) {
			DateUtils.log.error("转换日期出错");
			e.printStackTrace();
		}
		return i;
	}

	/**
	 * 比较指定时间与系统时间相差的天数
	 * 
	 * @param date指定时间
	 *            ("yyyy-mm-dd" 形式)
	 */
	public static int compareTime(String date) {
		Date dates;
		int i = 0;
		try {
			dates = DateUtils.convertStringToDate(date);
			i = (int) ((dates.getTime() - System.currentTimeMillis()) / 24 / 3600 / 1000);
		}
		catch (ParseException e) {
			DateUtils.log.error("转换日期出错");
			e.printStackTrace();
		}
		return i;
	}

	/**
	 * This method generates a string representation of a date based on the
	 * System Property 'dateFormat' in the format you specify on input
	 * 
	 * @param aDate
	 *            A date to convert
	 * @return a string representation of the date
	 */
	public static final String convertDateToString(Date aDate) {
		return DateUtils.getDateTime(DateUtils.getDateTimePattern(), aDate);
	}

	/**
	 * This method converts a String to a date using the datePattern
	 * 
	 * @param strDate
	 *            the date to convert (in format MM/dd/yyyy)
	 * @return a date object
	 * @throws ParseException
	 */
	public static Date convertStringToDate(String strDate) throws ParseException {
		Date aDate = null;

		try {
			if (DateUtils.log.isDebugEnabled()) {
				DateUtils.log.debug("converting date with pattern: " + DateUtils.getDatePattern());
			}

			aDate = DateUtils.convertStringToDate(DateUtils.getDatePattern(), strDate);
		}
		catch (ParseException pe) {
			DateUtils.log.error("Could not convert '" + strDate + "' to a date, throwing exception");
			pe.printStackTrace();
			throw new ParseException(pe.getMessage(), pe.getErrorOffset());

		}

		return aDate;
	}

	/**
	 * This method generates a string representation of a date/time in the
	 * format you specify on input
	 * 
	 * @param aMask
	 *            the date pattern the string is in
	 * @param strDate
	 *            a string representation of a date
	 * @return a converted Date object
	 * @see java.text.SimpleDateFormat
	 * @throws ParseException
	 */
	public static final Date convertStringToDate(String aMask, String strDate) throws ParseException {
		SimpleDateFormat df = null;
		Date date = null;
		df = new SimpleDateFormat(aMask);

		DateUtils.log.info("converting '" + strDate + "' to date with mask '" + aMask + "'");

		try {
			date = df.parse(strDate);
		}
		catch (ParseException pe) {
			// log.error("ParseException: " + pe);
			throw new ParseException(pe.getMessage(), pe.getErrorOffset());
		}

		return (date);
	}

	public static Date convertStringToDateTime(String strDate) throws ParseException {
		Date aDate = null;

		try {
			if (DateUtils.log.isDebugEnabled()) {
				DateUtils.log.debug("converting date with pattern: " + DateUtils.getDateTimePattern());
			}

			aDate = DateUtils.convertStringToDate(DateUtils.getDateTimePattern(), strDate);
		}
		catch (ParseException pe) {
			DateUtils.log.error("Could not convert '" + strDate + "' to a date, throwing exception");
			pe.printStackTrace();
			throw new ParseException(pe.getMessage(), pe.getErrorOffset());

		}

		return aDate;
	}

	public static String dateToString(Date date, String pattern) {
		SimpleDateFormat df = new SimpleDateFormat(pattern);
		return df.format(date);
	}

	/**
	 * This method attempts to convert an Oracle-formatted date in the form
	 * dd-MMM-yyyy to mm/dd/yyyy.
	 * 
	 * @param aDate
	 *            date from database as a string
	 * @return formatted string for the ui
	 */
	public static final String getDate(Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";

		if (aDate != null) {
			df = new SimpleDateFormat(DateUtils.getDatePattern());
			returnValue = df.format(aDate);
		}

		return (returnValue);
	}

	/**
	 * Return default datePattern (yyyy-MM-dd)
	 * 
	 * @return a string representing the date pattern on the UI
	 */
	public static synchronized String getDatePattern() {
		// Locale locale = LocaleContextHolder.getLocale();
		try {
			// defaultDatePattern =
			// ResourceBundle.getBundle(Constants.BUNDLE_KEY,
			// locale).getString("date.format");
			DateUtils.defaultDatePattern = "yyyy-MM-dd";
		}
		catch (MissingResourceException mse) {
			// defaultDatePattern = "MM/dd/yyyy";
			DateUtils.defaultDatePattern = "yyyy-MM-dd";
		}

		return DateUtils.defaultDatePattern;
	}

	public static final String getDateTime() {
		long time = System.currentTimeMillis();
		Date date = new Date(time);
		SimpleDateFormat df = null;
		String returnValue = "";

		if (date != null) {
			df = new SimpleDateFormat(DateUtils.getDateTimePattern());
			returnValue = df.format(date);
		}

		return (returnValue);
	}

	public static final Date getDateTime(String aMask) {
		SimpleDateFormat df = null;
		String returnValue = "";
		df = new SimpleDateFormat(aMask);
		returnValue = df.format(new Date());
		try {
			return df.parse(returnValue);
		}
		catch (ParseException e) {
			DateUtils.log.error(e);
			return new Date();
		}
	}

	/**
	 * This method generates a string representation of a date's date/time in
	 * the format you specify on input
	 * 
	 * @param aMask
	 *            the date pattern the string is in
	 * @param aDate
	 *            a date object
	 * @return a formatted string representation of the date
	 * @see java.text.SimpleDateFormat
	 */
	public static final String getDateTime(String aMask, Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";

		if (aDate == null) {
			DateUtils.log.error("aDate is null!");
		} else {
			df = new SimpleDateFormat(aMask);
			returnValue = df.format(aDate);
		}

		return (returnValue);
	}

	public static String getDateTimePattern() {
		return DateUtils.getDatePattern() + " HH:mm:ss";
	}

	/**
	 * 获取days天 时间总和
	 * 
	 * @param days
	 *            天数
	 * @return
	 */
	public static long getDaysTime(int days) {
		return MILLSECOND * SECOND * MINITE * HOUR * days;
	}

	/**
	 * 系统时间向后推20天 sunyuanhua
	 */

	public static String getEndTime(int dayNum) {
		java.sql.Timestamp date1 = new java.sql.Timestamp(System.currentTimeMillis() + (dayNum * 24 * 3600 * 1000));
		String endTime = date1.toString();
		return endTime.substring(0, 19);
	}

	/**
	 * 将传入时间与当前时间进行计算，返回时间差。格式为最大时间的时间数加上单位，如1天前、2小时前。 如果时间在一分钟内，则返回刚刚
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static String getLeftTime(long start, long end) {
		long left = end - start;
		long day = left / (MILLSECOND * SECOND * MINITE * HOUR);
		long hour = (left % (MILLSECOND * SECOND * MINITE * HOUR)) / (MILLSECOND * SECOND * MINITE);
		long min = ((left % (MILLSECOND * SECOND * MINITE * HOUR)) % (MILLSECOND * SECOND * MINITE)) / (MILLSECOND * SECOND);
		long second = (((left % (MILLSECOND * SECOND * MINITE * HOUR)) % (MILLSECOND * SECOND * MINITE)) % (MILLSECOND * SECOND)) / MILLSECOND;
		if (day != 0) {
			return day + "天前";
		} else if (hour != 0) {
			return hour + "小时前";
		} else if (min != 0) {
			return min + "分钟前";
		} else if (second != 0) {
			return second + "秒前";
		} else {
			return "刚刚";
		}
	}

	/** 获取多少天之前的时间 **/
	public static String getTime(int day) {
		// Format f = new SimpleDateFormat("yyyy-MM-dd");
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DATE, day);
		return new SimpleDateFormat("yyyyMMdd").format(c.getTime());
	}

	public static Date getTimeNow() {
		return DateUtils.getDateTime(DateUtils.getDateTimePattern());
	}

	/**
	 * This method returns the current date time in the format: MM/dd/yyyy HH:MM
	 * a
	 * 
	 * @param theTime
	 *            the current time
	 * @return the current date/time
	 */
	public static String getTimeNow(Date theTime) {
		return DateUtils.getDateTime(DateUtils.timePattern, theTime);
	}

	/**
	 * This method returns the current date in the format: MM/dd/yyyy
	 * 
	 * @return the current date
	 * @throws ParseException
	 */
	public static Calendar getToday() throws ParseException {
		Date today = new Date();
		SimpleDateFormat df = new SimpleDateFormat(DateUtils.getDatePattern());

		// This seems like quite a hack (date -> string -> date),
		// but it works ;-)
		String todayAsString = df.format(today);
		Calendar cal = new GregorianCalendar();
		cal.setTime(DateUtils.convertStringToDate(todayAsString));

		return cal;
	}

	/**
	 * 获取今天的零点的long型时间
	 * 
	 * @return
	 */
	public static long getZeroLongTime() {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		Long todayZeroTime = calendar.getTimeInMillis() - (23 * MINITE * SECOND * MILLSECOND + 59 * SECOND * MILLSECOND + 59 * MILLSECOND);// 今日零点时间
		return todayZeroTime;
	}

	/**
	 * 获取days天前的零点的long型时间
	 * 
	 * @param days
	 * @return
	 */
	public static long getZeroLongTimeServalDays(int days) {
		return getZeroLongTime() - days * HOUR * MINITE * SECOND * MILLSECOND;
	}

	/**
	 * 时间戳转换为日期
	 */
	public static Date long2Date(Long timestamp) {
		return new Date(timestamp);
	}

	/**
	 * 时间戳转换为日期字符串
	 */
	public static String long2DateString(Long timestamp) {
		return DateUtils.getDateTime(DateUtils.getDateTimePattern(), new Date(timestamp));
	}

	/**
	 * 时间戳转换为日期字符串
	 */
	public static String longToDateString(Long timestamp, String pattern) {
		SimpleDateFormat df = new SimpleDateFormat(pattern);

		return df.format(new Date(timestamp));
	}

	public static void main(String[] args) throws ParseException {

		System.out.println(System.currentTimeMillis());

		System.out.println(System.currentTimeMillis() + 30000);

		System.out.println(getLeftTime(1290996553873l, 1290996583921l));

		System.out.println(toLong("20101201112745"));

		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
		String time = sf.format(DateUtils.long2Date(DateUtils.stringToLong("2011-1-1 00:00:00")));
		System.out.println(time);
		Date date = sf.parse(time);
		System.out.println(date.getTime());
	}

	/**
	 * 时间格式的字符串,转换为long
	 * 
	 * @throws ParseException
	 */
	public static long stringToLong(String dateString) throws ParseException {
		if (dateString != null && !"".equals(dateString)) {
			Date date = null;
			if (dateString.length() == 10) {
				date = DateUtils.convertStringToDate(DateUtils.getDatePattern(), dateString);
			} else {
				date = DateUtils.convertStringToDate(DateUtils.getDateTimePattern(), dateString);
			}
			if (date != null) {
				return date.getTime();
			}
		}
		return -1;
	}

	public static long toLong(String dateString) throws ParseException {
		if (dateString != null && !"".equals(dateString)) {
			SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
			Date date = sf.parse(dateString);
			return date.getTime();
		}
		return 0;
	}

	/**
	 * 获取今天在一年中的天数
	 * 
	 * @return
	 */
	public int getDayOfYear() {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.add(Calendar.DATE, 0);
		return calendar.get(Calendar.DAY_OF_YEAR);
	}
}
